package org.flashamaphone.tones
{
	public class Note extends Tone
	{
		public static const C 		:String = "C";
		public static const CSHARP	:String = "C#";
		public static const DFLAT	:String = "Db";
		public static const D 		:String = "D";
		public static const DSHARP	:String = "D#";
		public static const EFLAT	:String = "Eb";
		public static const E 		:String = "E"; 
		public static const F 		:String = "F";
		public static const FSHARP	:String = "F#";
		public static const GFLAT  	:String = "Gb";
		public static const G		:String = "G";
		public static const GSHARP 	:String = "G#";
		public static const AFLAT	:String = "Ab";
		public static const A 		:String = "A"; 
		public static const ASHARP	:String = "A#";
		public static const	BFLAT	:String = "Bb";
		public static const B 		:String = "B"; 
		
		/** octave */
		protected var _octave:int;
		
		/** current note designation */
		protected var _currentDesignation:String;
		
		/** sharp note designations */
		protected var _sharpDesignations:Array = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"];
		
		/** flat note designations */
		protected var _flatDesignations:Array  = ["A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab"];
		
		/** 
		 * constructor
		 * 
		 * @param note designation
		 * @param octave
		 * @param duration
		 */
		public function Note(value:String = "", octave:int = 4, duration:Number = 1)
		{
			super();
			this.octave = octave;
			designation = value;
			this.duration = duration;
			
			buildNote();
		}
		
		/**
		 * designation setter
		 * 
		 * @param note designation
		 */
		public function set designation(value:String):void {
			_currentDesignation = value;
			buildNote();
		}
		
		/**
		 * designation getter
		 * 
		 * @return note designation
		 */
		public function get designation():String {
			return _currentDesignation;
		}
		
		/**
		 * octave setter
		 * 
		 * @param octave
		 */
		public function set octave(value:int):void {
			_octave = value;
			buildNote();
		}
		
		/**
		 * octave getter
		 * 
		 * @return octave
		 */
		public function get octave():int {
			return _octave;
		}
		
		
		/** 
		 * setter for the current note designation
		 * 
		 * @param value
		 */
		public function buildNote():void {
			var indx:int = _sharpDesignations.indexOf(_currentDesignation);
			
			if (indx == -1) {
				indx = _flatDesignations.indexOf(_currentDesignation);
			}
			
			if (indx != -1) {
				//adjust index for octave
				indx += (octave-4) * _sharpDesignations.length;
				frequency = 440 * (Math.pow(2, indx/12));
			}
		}
	}
}